// BSLLS-off

// Этот плагин выполняет переименование переменных если это возможно.
// При возникновении конфликтов регистрирует ошибку, которая указывает на конфликтную переменную.

// Пример ожидаемой структуры параметров (json):
// {"СтароеИмя1": "НовоеИмя1", "СтароеИмя2": "НовоеИмя2"}

Перем Токены;
Перем Типы;
Перем ТаблицаОшибок;
Перем ТаблицаЗамен;
Перем Директивы;

Перем Результат;

Перем ПрефиксПеременныхИПроцедур;
Перем ОписаниеКонфигурации;
Перем МассивИменОбщихМодулей;
Перем КонтекстМетодаКлиентский;
Перем ДоступенКонтекстФормы;
Перем ИмяМетода;
Перем ЭтоМодульФормы;

Процедура Открыть(Парсер, Параметры) Экспорт
	Типы = Парсер.Типы();
	ТаблицаОшибок = Парсер.ТаблицаОшибок();
	ТаблицаЗамен = Парсер.ТаблицаЗамен();
	Директивы = Парсер.Директивы();
	Токены = Парсер.Токены();
	
	Результат = Новый Массив;

	ПрефиксПеременныхИПроцедур=Параметры.ПрефиксПеременныхИПроцедур;
	ОписаниеКонфигурации=Параметры.ОписаниеКонфигурации;
	ЭтоМодульФормы=Параметры.ЭтоМодульФормы;

	МассивИменОбщихМодулей=Новый Массив;
	
	Для Каждого Модуль Из ОписаниеКонфигурации.ОбщиеМодули Цикл
		// Если Модуль.ЭтоМодульМенеджера Тогда
		// 	Продолжить;
		// КонецЕсли;
		МассивИменОбщихМодулей.Добавить(НРег(Модуль.Имя));
	КонецЦикла;
КонецПроцедуры // Открыть()

Функция Закрыть() Экспорт
	Возврат СтрСоединить(Результат);
КонецФункции // Закрыть()

Функция Подписки() Экспорт
	Перем Подписки;
	Подписки = Новый Массив;
	Подписки.Добавить("ПосетитьОбъявлениеМетода");
	Подписки.Добавить("ПосетитьВыражениеИдентификатор");
	Подписки.Добавить("ПокинутьОбъявлениеМетода");
	Возврат Подписки;
КонецФункции // Подписки()

#Область РеализацияПодписок

Процедура ПосетитьОбъявлениеМетода(Объявление) Экспорт
	Если ЭтоМодульФормы Тогда
		Если Объявление.Сигнатура.Директивы.Количество()=0 Тогда
			КонтекстМетодаКлиентский=Ложь;
			ДоступенКонтекстФормы=Истина;
		Иначе
			Если Объявление.Сигнатура.Директивы[0].Директива=Директивы.НаКлиенте Тогда
				КонтекстМетодаКлиентский=Истина;
			Иначе
				КонтекстМетодаКлиентский=Ложь;
			КонецЕсли;

			Если Объявление.Сигнатура.Директивы[0].Директива=Директивы.НаКлиенте
				Или Объявление.Сигнатура.Директивы[0].Директива=Директивы.НаСервере
				Или Объявление.Сигнатура.Директивы[0].Директива=Директивы.НаКлиентеНаСервере Тогда
				ДоступенКонтекстФормы=Истина;
			Иначе
				ДоступенКонтекстФормы = Ложь;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

	ИмяМетода=Объявление.Сигнатура.Имя;
КонецПроцедуры

Процедура ПосетитьВыражениеИдентификатор(ВыражениеИдентификатор) Экспорт
	
	Объявление = ВыражениеИдентификатор.Голова.Имя;
	
	Если МассивИменОбщихМодулей.Найти(НРег(Объявление))=Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоМодульФормы 
		И КонтекстМетодаКлиентский Тогда
		
		Если ДоступенКонтекстФормы Тогда
			ТекстЗамены=ПрефиксПеременныхИПроцедур+"ОбщийМодульПоИмени("""+Объявление+""", "+ПрефиксПеременныхИПроцедур+"КэшОбщихМодулей, ЭтаФорма)";
		Иначе
			ТекстЗамены=ПрефиксПеременныхИПроцедур+"ОбщийМодульПоИмени("""+Объявление+""", "+ПрефиксПеременныхИПроцедур+"КэшОбщихМодулей)";
		КонецЕсли;
	Иначе
		ТекстЗамены=ПрефиксПеременныхИПроцедур+"ОбщийМодульПоИмени("""+Объявление+""")";
	КонецЕсли;
	ДанныеТокена = ВыражениеИдентификатор.Начало;
	Замена(ТекстЗамены, ДанныеТокена);
КонецПроцедуры

Процедура ПокинутьОбъявлениеМетода(Объявление) Экспорт
	КонтекстМетодаКлиентский=Ложь;
	ДоступенКонтекстФормы=Ложь;
	ИмяМетода="";
КонецПроцедуры


#КонецОбласти // РеализацияПодписок

Процедура Ошибка(Текст, Начало, Конец = Неопределено, ЕстьЗамена = Ложь)
	Ошибка = ТаблицаОшибок.Добавить();
	Ошибка.Источник = "КонвертацияВызоваМетодовМодулейМенеджераИнструметров";
	Ошибка.Текст = Текст;
	Ошибка.ПозицияНачала = Начало.Позиция;
	Ошибка.НомерСтрокиНачала = Начало.НомерСтроки;
	Ошибка.НомерКолонкиНачала = Начало.НомерКолонки;
	Если Конец = Неопределено Или Конец = Начало Тогда
		Ошибка.ПозицияКонца = Начало.Позиция + Начало.Длина;
		Ошибка.НомерСтрокиКонца = Начало.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Начало.НомерКолонки + Начало.Длина;
	Иначе
		Ошибка.ПозицияКонца = Конец.Позиция + Конец.Длина;
		Ошибка.НомерСтрокиКонца = Конец.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Конец.НомерКолонки + Конец.Длина;
	КонецЕсли;
	Ошибка.ЕстьЗамена = ЕстьЗамена;
КонецПроцедуры

Процедура Замена(Текст, Начало, Конец = Неопределено)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "КонвертацияВызоваМетодовМодулейМенеджераИнструметров";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Начало.Позиция;
	Если Конец = Неопределено Тогда
		НоваяЗамена.Длина = Начало.Длина;
	Иначе
		НоваяЗамена.Длина = Конец.Позиция + Конец.Длина - Начало.Позиция;
	КонецЕсли;
КонецПроцедуры

Процедура Вставка(Текст, Позиция)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "КонвертацияВызоваМетодовМодулейМенеджераИнструметров";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Позиция;
	НоваяЗамена.Длина = 0;
КонецПроцедуры